from scipy.signal import convolve2d
import numpy as np
import matplotlib.pyplot as plt

def run_2d_life(size=100, steps=100, init_density=0.3):
    """
    运行 2D 生命游戏
    :param size: 网格边长（方阵）
    :param steps: 模拟步数
    :param init_density: 初始激活元胞密度
    :return: 网格历史状态 (steps+1 × size × size)
    """
    # 初始随机状态
    grid = np.random.choice([0, 1], size=(size, size), p=[1 - init_density, init_density])
    history = np.zeros((steps + 1, size, size), dtype=int)
    history[0] = grid.copy()

    # 定义邻居卷积核（8连通）
    kernel = np.array([[1, 1, 1],
                       [1, 0, 1],
                       [1, 1, 1]])

    for t in range(steps):
        # 计算每个元胞的活邻居数
        neighbors = convolve2d(grid, kernel, mode="same", boundary="wrap")
        # 应用规则
        grid = np.where(
            (grid == 1) & ((neighbors < 2) | (neighbors > 3)), 0, grid  # 死亡条件
        )
        grid = np.where(
            (grid == 0) & (neighbors == 3), 1, grid  # 出生条件
        )
        history[t + 1] = grid.copy()

    return history


# 可视化
history = run_2d_life(size=50, steps=100)
plt.figure(figsize=(8, 8))
plt.imshow(history[-1], cmap="binary")
plt.title("Game of Life (Final State)")
plt.axis("off")
plt.show()
